part of '../index.dart';

class BuildMessageList<T, E extends DateTime> extends StatelessWidget {
  final ScrollController scrollController;
  final List<T> sortedList;
  final E Function(T value) groupBy;
  final bool Function(E left, E right) groupRange;
  final Widget Function(T value) groupHeaderBuilder;
  final Widget Function(BuildContext context, T value) itemBuilder;
  final EasyRefreshController refreshController;
  final void Function()? onRefresh;
  final void Function()? onLoading;

  const BuildMessageList({
    super.key,
    required this.scrollController,
    required this.sortedList,
    required this.groupBy,
    required this.groupRange,
    required this.groupHeaderBuilder,
    required this.itemBuilder,
    required this.refreshController,
    this.onRefresh,
    this.onLoading,
  });

  bool _isSeparator(int index) => index.isOdd;

  Widget _buildGroupSeparator(T element) => groupHeaderBuilder(element);

  @override
  Widget build(BuildContext context) {
    return CustomPullScrollView(
      controller: refreshController,
      onLoading: onLoading,
      builder: (context, physics) => CustomScrollView(
        controller: scrollController,
        physics: physics,
        reverse: true,
        keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
        slivers: [
          ExtendedSliverList(
            delegate: SliverChildBuilderDelegate((context, index) {
              final actualIndex = index ~/ 2;
              if (index == sortedList.length * 2 - 1) {
                return Padding(
                  padding: const EdgeInsets.only(top: 10),
                  child: _buildGroupSeparator(sortedList[actualIndex]),
                );
              }
              if (_isSeparator(index)) {
                if (actualIndex + 1 >= sortedList.length) {
                  return const SizedBox.shrink();
                }
                final curr = groupBy(sortedList[actualIndex]);
                final prev = groupBy(sortedList[actualIndex + 1]);
                if (groupRange(curr, prev)) return const SizedBox.shrink();
                return _buildGroupSeparator(sortedList[actualIndex]);
              }
              return itemBuilder(context, sortedList[actualIndex]);
            }, childCount: sortedList.length * 2),
            extendedListDelegate:
                const ExtendedListDelegate(closeToTrailing: true),
          )
        ],
      ),
    );
  }
}
